package com.newidea.jiangong.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.newidea.jiangong.component.HeatComponent;
import com.newidea.jiangong.constant.HeatCons;
import com.newidea.jiangong.dto.Boiler;
import com.newidea.jiangong.dto.FacilityState;
import com.newidea.jiangong.dto.HeatSys;
import com.newidea.jiangong.dto.Pump;
import com.newidea.jiangong.entity.HeatFacility;
import com.newidea.jiangong.entity.IndoorTemMonitor;
import com.newidea.jiangong.entity.IndoorTemMonitorHead;
import com.newidea.jiangong.entity.MachineMonitor;
import com.newidea.jiangong.restful.ApiResult;
import com.newidea.jiangong.service.HeatFacilityService;
import com.newidea.jiangong.service.IndoorTemMonitorHeadService;
import com.newidea.jiangong.service.IndoorTemMonitorService;
import com.newidea.jiangong.service.MachineMonitorService;
import com.newidea.jiangong.utils.DatunUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping(value = "/api/datun")
@Tag(name = "大屯供热", description = "获取大屯供热数据接口")
public class DatunController {

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private final HeatComponent heatComponent;
    private final HeatFacilityService heatFacilityService;
    private final MachineMonitorService machineMonitorService;
    private final IndoorTemMonitorService indoorTemMonitorService;
    private final IndoorTemMonitorHeadService indoorTemMonitorHeadService;

    public DatunController(
            HeatComponent heatComponent, HeatFacilityService heatFacilityService,
            MachineMonitorService machineMonitorService, IndoorTemMonitorService indoorTemMonitorService,
            IndoorTemMonitorHeadService indoorTemMonitorHeadService
    ) {
        this.heatComponent = heatComponent;
        this.heatFacilityService = heatFacilityService;
        this.machineMonitorService = machineMonitorService;
        this.indoorTemMonitorService = indoorTemMonitorService;
        this.indoorTemMonitorHeadService = indoorTemMonitorHeadService;
    }

    @GetMapping("/heatFacility")
    @Operation(summary = "获取Modbus数据", description = "获取最新的数据")
    public ResponseEntity<ApiResult<List<HeatFacility>>> getHeatFacility(
            @Parameter(description = "数据所属公司：大屯、建邦枫景、华威")
            @RequestParam(required = false) String company
    ) {
        QueryWrapper<HeatFacility> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(company)) {
            wrapper.eq("company", company);
        }
        // 是否获取最新的数据
        wrapper.eq("newest", true);
        return ApiResult.ok(heatFacilityService.list(wrapper));
    }

    @GetMapping("/indoorTemMonitor")
    @Operation(summary = "获取室温监控数据", description = "获取最新的数据")
    public ResponseEntity<ApiResult<List<IndoorTemMonitor>>> getIndoorTemMonitor(
            @Parameter(description = "数据所属公司：大屯、建邦枫景、华威")
            @RequestParam(required = false) String company
    ) {
        QueryWrapper<IndoorTemMonitor> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(company)) {
            wrapper.eq("company", company);
        }
        // 是否获取最新的数据
        wrapper.eq("newest", true);
        return ApiResult.ok(indoorTemMonitorService.list(wrapper));
    }

    @GetMapping("/indoorTemMonitorHead")
    @Operation(summary = "获取室温监控分析数据", description = "获取最新的数据")
    public ResponseEntity<ApiResult<List<IndoorTemMonitorHead>>> getIndoorTemMonitorHead(
            @Parameter(description = "数据所属公司：大屯、建邦枫景、华威")
            @RequestParam(required = false) String company
    ) {
        QueryWrapper<IndoorTemMonitorHead> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(company)) {
            wrapper.eq("company", company);
        }
        // 是否获取最新的数据
        wrapper.eq("newest", true);
        return ApiResult.ok(indoorTemMonitorHeadService.list(wrapper));
    }

    @GetMapping("/machineMonitor")
    @Operation(summary = "获取机房监控数据", description = "获取最新的数据")
    public ResponseEntity<ApiResult<List<MachineMonitor>>> getMachineMonitor(
            @Parameter(description = "数据所属公司：大屯、建邦枫景、华威")
            @RequestParam(required = false) String company
    ) {
        QueryWrapper<MachineMonitor> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(company)) {
            wrapper.eq("company", company);
        }
        // 是否获取最新的数据
        wrapper.eq("newest", true);
        return ApiResult.ok(machineMonitorService.list(wrapper));
    }

    @GetMapping("/indoorTemMonitor/history")
    @Operation(
            summary = "获取某个楼栋的室温历史记录",
            responses = {
                    @ApiResponse(
                            responseCode = "200",
                            content = @Content(
                                    mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE,
                                    examples = @ExampleObject(
                                            name = "返回样例",
                                            description = "create_time=采集时间；column1=室温",
                                            value = "{\n" +
                                                    "    \"state\": {\n" +
                                                    "        \"code\": 0,\n" +
                                                    "        \"description\": \"ok\"\n" +
                                                    "    },\n" +
                                                    "    \"data\": [\n" +
                                                    "        {\n" +
                                                    "            \"column1\": \"23.4\",\n" +
                                                    "            \"create_time\": \"2024-01-04 17:30:13\"\n" +
                                                    "        },\n" +
                                                    "        {\n" +
                                                    "            \"column1\": \"23.2\",\n" +
                                                    "            \"create_time\": \"2024-01-04 18:00:14\"\n" +
                                                    "        }\n" +
                                                    "    ]\n" +
                                                    "}"
                                    )
                            )
                    )
            }
    )
    public ResponseEntity<ApiResult<List<Map<String, Object>>>> getHistoryIndoorTemMonitor(
            @Parameter(description = "要获取的楼栋") @RequestParam String deviceName
    ) {
        // 获取最新的依次采集时间
        String newDate = heatComponent.getNewDate("indoor_tem_monitor", HeatCons.DA_TUN);
        // 获取历史数据的开始时间
        String startDate = LocalDateTime.parse(newDate, formatter).minusHours(6).format(formatter);

        QueryWrapper<IndoorTemMonitor> wrapper = new QueryWrapper<>();
        wrapper.select("create_time", "column1");
        wrapper.orderByAsc("create_time");
        wrapper.eq("device_name", deviceName);
        wrapper.between("create_time", startDate, newDate);
        return ApiResult.ok(indoorTemMonitorService.listMaps(wrapper));
    }

    @GetMapping("/indoorTemMonitorHead/history")
    @Operation(summary = "获取室温监控分析历史记录")
    public ResponseEntity<ApiResult<List<IndoorTemMonitorHead>>> getHistoryIndoorTemMonitorHead() {
        // 获取最新的依次采集时间
        String newDate = heatComponent.getNewDate("indoor_tem_monitor_head", HeatCons.DA_TUN);
        // 获取历史数据的开始时间
        String startDate = LocalDateTime.parse(newDate, formatter).minusHours(6).format(formatter);

        QueryWrapper<IndoorTemMonitorHead> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("create_time");
        wrapper.between("create_time", startDate, newDate);
        return ApiResult.ok(indoorTemMonitorHeadService.list(wrapper));
    }

    @GetMapping("/machineMonitor/history")
    @Operation(summary = "获取机房监控历史数据")
    public ResponseEntity<ApiResult<List<MachineMonitor>>> getHistoryMachineMonitor(
            @Parameter(description = "项目名称") @RequestParam String projectName,
            @Parameter(description = "设备名称") @RequestParam String deviceName
    ) {
        // 获取最新的依次采集时间
        String newDate = heatComponent.getNewDate("machine_monitor", HeatCons.DA_TUN);
        // 获取历史数据的开始时间
        String startDate = LocalDateTime.parse(newDate, formatter).minusHours(6).format(formatter);

        QueryWrapper<MachineMonitor> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("create_time");
        wrapper.eq("project_name", projectName);
        wrapper.eq("device_name", deviceName);
        wrapper.between("create_time", startDate, newDate);
        return ApiResult.ok(machineMonitorService.list(wrapper));
    }

    @GetMapping("/modbus/history")
    @Operation(
            summary = "获取modbus设备地址值的历史数据",
            responses = {
                    @ApiResponse(
                            responseCode = "200",
                            content = @Content(
                                    mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE,
                                    examples = @ExampleObject(
                                            name = "返回样例",
                                            description = "create_time=采集时间；name=设备名称；value=值",
                                            value = "{\n" +
                                                    "    \"state\": {\n" +
                                                    "        \"code\": 0,\n" +
                                                    "        \"description\": \"ok\"\n" +
                                                    "    },\n" +
                                                    "    \"data\": [\n" +
                                                    "        {\n" +
                                                    "            \"create_time\": \"2024-01-04 18:25:00\",\n" +
                                                    "            \"name\": \"锅炉1供水温度\",\n" +
                                                    "            \"value\": \"74.00\"\n" +
                                                    "        },\n" +
                                                    "        {\n" +
                                                    "            \"create_time\": \"2024-01-04 18:30:00\",\n" +
                                                    "            \"name\": \"锅炉1供水温度\",\n" +
                                                    "            \"value\": \"74.00\"\n" +
                                                    "        }\n" +
                                                    "    ]\n" +
                                                    "}"
                                    )
                            )
                    )
            }
    )
    public ResponseEntity<ApiResult<List<Map<String, String>>>> getHistoryModbus() {
        // 获取最新的依次采集时间
        String newDate = heatComponent.getNewDate("heat_facility", HeatCons.DA_TUN);
        // 获取历史数据的开始时间
        String startDate = LocalDateTime.parse(newDate, formatter).minusHours(6).format(formatter);

        QueryWrapper<HeatFacility> wrapper = new QueryWrapper<>();
        wrapper.select("create_time", "address", "value");
        wrapper.orderByAsc("create_time");
        wrapper.eq("company", HeatCons.DA_TUN);
        wrapper.likeRight("address", "40");
        wrapper.between("create_time", startDate, newDate);
        Map<String, Map<String, String>> collect = heatFacilityService.list(wrapper).stream()
                // 根据采集时间进行分组，
                .collect(Collectors.groupingBy(
                        HeatFacility::getCreateTime,
                        Collectors.toMap(HeatFacility::getAddress, HeatFacility::getValue)
                ));
        // 排序
        TreeMap<String, Map<String, String>> sort = MapUtil.sort(collect);

        List<Map<String, String>> list = new ArrayList<>();
        // 将key设置为采集时间
        sort.forEach((key, value) -> {
            value.put("createTime", key);
            list.add(value);
        });
        return ApiResult.ok(list);
    }

    @GetMapping("/modbus/heatSys")
    @Operation(summary = "获取modbus的供热系统数据")
    public ResponseEntity<ApiResult<List<HeatSys>>> getModbusHeatSys() {
        // 获取设备地址对应的值
        Map<String, String> facilityMap = heatFacilityService.getFacilityMap(HeatCons.DA_TUN);
        // 获取供热系统相关的数据
        HeatSys heatSys = DatunUtil.getHeatSys(facilityMap);
        // 最新的采集时间
        heatSys.setCollectDate(heatComponent.getNewDate("heat_facility", HeatCons.DA_TUN));
        // 室外温度
        heatSys.setOutdoorTemperature(facilityMap.get("40085"));
        return ApiResult.ok(CollUtil.newArrayList(heatSys));
    }

    @GetMapping("/modbus/boiler")
    @Operation(summary = "获取modbus中锅炉的数据")
    public ResponseEntity<ApiResult<List<Boiler>>> getModbusBoiler() {
        // 获取设备地址对应的值
        Map<String, String> facilityMap = heatFacilityService.getFacilityMap(HeatCons.DA_TUN);
        return ApiResult.ok(DatunUtil.getBoilerList(facilityMap));
    }

    @GetMapping("/modbus/pump")
    @Operation(summary = "获取modbus中泵的数据")
    public ResponseEntity<ApiResult<List<Pump>>> getModbusPump() {
        // 获取设备地址对应的值
        Map<String, String> facilityMap = heatFacilityService.getFacilityMap(HeatCons.DA_TUN);
        return ApiResult.ok(DatunUtil.getPumpList(facilityMap));
    }

    @GetMapping("/modbus/facilityState")
    @Operation(summary = "获取modbus中设备的状态")
    public ResponseEntity<ApiResult<List<FacilityState>>> getFacilityStateList() {
        // 获取设备地址对应的值
        Map<String, String> facilityMap = heatFacilityService.getFacilityMap(HeatCons.DA_TUN);
        return ApiResult.ok(DatunUtil.getFacilityStateList(facilityMap));
    }
}
